using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections;
using System.Windows.Forms;
using System.Globalization;
using System.Reflection;

namespace SIMc
{
    public partial class XMLContactList
    {
        XmlDocument xmlDoc;
        string path;

        public XMLContactList(string appPath)
        {
            this.path = appPath + "contactList.xml";
            xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(path);
            }
            catch (Exception e)
            {
                createContactList();
            }
        }

        internal bool addProfile(int profileID)
        {

            XmlElement accElem = xmlDoc.CreateElement("profile");
            xmlDoc.DocumentElement.AppendChild(accElem);
            XmlAttribute IDAttr = xmlDoc.CreateAttribute("ID");
            IDAttr.Value = profileID.ToString();
            accElem.Attributes.Append(IDAttr);

            XmlElement groupElem = xmlDoc.CreateElement("list");
            accElem.AppendChild(groupElem);

            XmlAttribute nameAttr = xmlDoc.CreateAttribute("name");
            nameAttr.Value = "General";
            groupElem.Attributes.Append(nameAttr);

            xmlDoc.Save(path);

            return true;
        }


        internal bool createContactList()
        {
            XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "no");

            XmlElement rootNode = xmlDoc.CreateElement("Contacts");
            xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement);
            xmlDoc.AppendChild(rootNode);


            for (int j = 1; j < 7; j++)
            {
                XmlElement accElem = xmlDoc.CreateElement("profile");
                rootNode.AppendChild(accElem);
                XmlAttribute IDAttr = xmlDoc.CreateAttribute("ID");
                IDAttr.Value = j.ToString();
                accElem.Attributes.Append(IDAttr);

                XmlElement groupElem = xmlDoc.CreateElement("list");
                accElem.AppendChild(groupElem);

                XmlAttribute nameAttr = xmlDoc.CreateAttribute("name");
                nameAttr.Value = "General";
                groupElem.Attributes.Append(nameAttr);

                for (int i = 1; i < 7; i++)
                {
                    XmlElement lContactElem = xmlDoc.CreateElement("entry");
                    groupElem.AppendChild(lContactElem);

                    XmlAttribute uriAttr = xmlDoc.CreateAttribute("uri");
                    uriAttr.Value = "sip:rv_user"+i+"@ngnlab.eu";
                    lContactElem.Attributes.Append(uriAttr);

                    XmlElement displayElem = xmlDoc.CreateElement("display-name");
                    displayElem.InnerXml = "rv_user" + i;
                    lContactElem.AppendChild(displayElem);
                }
            }
            xmlDoc.Save(path);

            return true;
        }


        internal ArrayList getContactGroups(int profileID)
        {
            ArrayList zoznam = new ArrayList();

            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode gNode in lNode.ChildNodes)
                    {
                        zoznam.Add(gNode.Attributes["name"].Value);
                    }
                }
            }
            return zoznam;
        }

        internal bool deleteAccount(int profileID)
        {

            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    xmlDoc.DocumentElement.RemoveChild(lNode);
                    break;
                }
            }
            xmlDoc.Save(path);
            return true;
        }

        TreeNode contactToTreeNode(XmlNode xmlNode)
        {
            TreeNode treeNode = new TreeNode();
            Contact contact = new Contact();
            contact.buddyID = -1;
            contact.status = "?";
            contact.onlineStatus = 0;

            contact.uri=xmlNode.Attributes["uri"].Value;
            contact.displayName = xmlNode.FirstChild.InnerXml;

            treeNode.Text = contact.displayName;
            treeNode.Tag = contact;

            return treeNode;
        }

        internal TreeView fillContactTreeView(TreeView treeView, int accountID)
        {
            treeView.Nodes.Clear();
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(accountID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {

                        TreeNode group = new TreeNode();
                        group.Tag = "grupa";
                        group.ImageIndex = 0;
                        group.Text = groupNode.Attributes["name"].Value;
                        treeView.Nodes.Add(group);
                        foreach (XmlNode contactNode in groupNode.ChildNodes)
                        {
                            TreeNode contact = contactToTreeNode(contactNode);
                            Contact kontaktik = (Contact)contact.Tag;
                            kontaktik.group = group.Text;
                            contact.Tag = kontaktik;
                            contact.ImageIndex = 2;
                            group.Nodes.Add(contact);
                        }
                        SortChildren(group);
                    }
                }
            }

            return treeView;
        }

        internal bool addGroup(int accountID, string name)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(accountID))
                {
                    // TODO testovat ci uz takato skupina neexistuje -> testujem pri formulari
                    XmlElement groupElem = xmlDoc.CreateElement("list");
                    XmlAttribute groupNameAttr = xmlDoc.CreateAttribute("name");
                    groupNameAttr.Value = name;
                    groupElem.Attributes.Append(groupNameAttr);
                    lNode.AppendChild(groupElem);
                }
            }
            xmlDoc.Save(path);
            return true;
        }
        //check -> NIE SOM ISTY :-/
        internal bool editContact(string group, Contact kontakt, int profileID, string oldUri)
        {

            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        if (groupNode.Attributes["name"].Value.Equals(group))
                        {
                            foreach (XmlNode contactNode in groupNode.ChildNodes)
                            {
                                if (contactNode.Attributes["uri"].Value.Equals(oldUri))
                                {
                                    contactNode.Attributes["uri"].Value = kontakt.uri;
                                    contactNode.FirstChild.InnerXml = kontakt.displayName;
                                }
                            }
                        }
                    }
                }
            }
            xmlDoc.Save(path);
            return true;
        }

        internal bool deleteContact(string group, Contact kontakt, int profileID)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        if (groupNode.Attributes["name"].Value.Equals(group))
                        {
                            foreach (XmlNode contactNode in groupNode.ChildNodes)
                            {
                                if (contactNode.Attributes["uri"].Value.Equals(kontakt.uri))
                                {
                                    groupNode.RemoveChild(contactNode);
                                }
                            }
                        }
                    }
                }
            }
            xmlDoc.Save(path);
            return true;
        }


        public bool isInContactList(int profileID, string uri){
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        foreach (XmlNode contactNode in groupNode.ChildNodes)
                        {
                            if (contactNode.Attributes["uri"].Value.Equals(uri))
                                    return true;
                        }
                    }
                }
            }
            return false;
        }

        public bool isDisplayNameInContactList(int profileID, string name)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        foreach (XmlNode contactNode in groupNode.ChildNodes)
                        {
                            if (contactNode.FirstChild.InnerXml.Equals(name))
                                    return true;
                        }
                    }
                }
            }
            return false;
        }

        public bool isGroupInContactList(int profileID, string name)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        if (groupNode.Attributes["name"].Value.Equals(name))
                            return true;
                    }
                }
            }
            return false;
        }

        public Contact getContactFromUri(int profileID, string uri){
            Contact kontakt= new Contact();
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        foreach (XmlNode contactNode in groupNode.ChildNodes)
                        {
                            if (contactNode.Attributes["uri"].Value.Equals(uri)) {
                                kontakt.displayName = contactNode.FirstChild.InnerXml;
                                kontakt.uri = contactNode.Attributes["uri"].Value;
                                return kontakt;
                            }
                        }
                    }
                }
            }
            return kontakt;
        }

        internal bool addContact(string group, Contact kontakt, int profileID)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(profileID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        if (groupNode.Attributes["name"].Value.Equals(group))
                        {

                            XmlElement entryElem = xmlDoc.CreateElement("entry");
                            XmlAttribute URIAttr = xmlDoc.CreateAttribute("uri");
                            URIAttr.Value = kontakt.uri;
                            groupNode.AppendChild(entryElem);
                            entryElem.Attributes.Append(URIAttr);

                            XmlElement displayElem = xmlDoc.CreateElement("display-name");
                            displayElem.InnerXml = kontakt.displayName;
                            entryElem.AppendChild(displayElem);
                        }
                    }
                }
            }
            xmlDoc.Save(path);
            return true;
        }
        
        // neviem naco som to v davnych donach napisal a na co to malo byt :(
        //internal ArrayList getContacts()
        //{
        //    ArrayList zoznam = new ArrayList();

        //    foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes.Item(0).ChildNodes.Item(0).ChildNodes)
        //    {
        //        if (lNode.Name.Equals("contact"))
        //        {
        //            zoznam.Add(lNode.FirstChild.NextSibling.InnerText);
        //        }
        //    }
        //    return zoznam;
        //}

        internal void deleteGroup(int accountID, string groupName)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(accountID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        if (groupNode.Attributes["name"].Value.Equals(groupName))
                        {
                            lNode.RemoveChild(groupNode);
                        }
                    }
                }
            }
            xmlDoc.Save(path);
        }

        internal void changeGroupName(int accountID, string oldGroup, string newGroup)
        {
            foreach (XmlNode lNode in xmlDoc.DocumentElement.ChildNodes)
            {
                if ((int.Parse(lNode.Attributes.Item(0).Value)).Equals(accountID))
                {
                    foreach (XmlNode groupNode in lNode.ChildNodes)
                    {
                        if (groupNode.Attributes["name"].Value.Equals(oldGroup))
                        {
                            groupNode.Attributes["name"].Value = newGroup;
                        }
                    }
                }
            }
            xmlDoc.Save(path);
        }

        public void SortChildren(TreeNode node)
        {
            if (node.Nodes.Count > 0)
            {
                
                TreeNode[] sort = new TreeNode[node.Nodes.Count];
                CompareInfo compare = CompareInfo.GetCompareInfo(0x0000040A);
                int i = 0;
                while(node.Nodes.Count != 0)
                {

                    int pos = -1;
                    for (int j = 0; j < node.Nodes.Count; j++)
                    {
                        if (node.Nodes[j] != null)
                        {
                            if (pos == -1 || compare.Compare(node.Nodes[j].Text, node.Nodes[pos].Text) < 0)
                            {
                                pos = j;
                            }
                        }
                    }
                    sort[i] = (TreeNode)node.Nodes[pos].Clone();
                    node.Nodes[pos].Remove();
                    //node.Nodes[pos] = null;
                    //sort[i].index = i;
                    i++;
                }
                node.Nodes.Clear();

                node.Nodes.AddRange(sort);
            }
        }


        internal TreeNode addContactToTree(Contact contact, TreeView TV_Contact)
        {
            TreeNode newNode = new TreeNode(contact.displayName);
            newNode.Tag= contact;
            newNode.ImageIndex = 2;
            foreach (TreeNode groupNode in TV_Contact.Nodes) {
                if (groupNode.Text.Equals(contact.group)) {
                    groupNode.Nodes.Add(newNode);
                    this.SortChildren(groupNode);
                    break;
                }
            }
            return newNode;
        }
    }
}
